﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using System.Data;
using System.Data.Entity;

using BeanOverflow.Models;

namespace BeanOverflow.Controllers
{
    public class QuestionAndResponsesModelController : Controller
    {
        private QuestionDBContext qdb = new QuestionDBContext();
        private ResponseDBContext rdb = new ResponseDBContext();

        /// <summary>
        /// Displays in tabular format all unanswered questions
        /// </summary>
        /// <returns>an ActionResult with all unanswered questions</returns>
        [Authorize]
        public ActionResult UnansweredIndex()
        {
            IEnumerable<Question> questions = qdb.Questions.ToList();

            List<QuestionAndResponsesModel> models = new List<QuestionAndResponsesModel>();

            foreach (Question curr in questions)
            {
                if (!hasAnswers(curr))
                {
                    models.Add(getAnswers(curr));
                }

            }


            return View(models);


        }


        // GET: /QuestionAndResponsesModel/RecentQuestions/5
        /// <summary>
        /// Displays in tabular format the last 10 ask questions
        /// </summary>
        /// <returns>an ActionResult containing the last 10 ask question with their respective responses(if any)</returns>
        [Authorize]
        public ActionResult RecentIndex()
        {
            IEnumerable<Question> questions = qdb.Questions.ToList();
            List<QuestionAndResponsesModel> models = new List<QuestionAndResponsesModel>();
            questions = questions.Reverse();
            foreach (Question curr in questions)
            {


                models.Add(getAnswers(curr));
                if (models.Count > 9)
                {
                    break;
                }
            }


            return View(models);


        }

        // GET: /QuestionAndResponsesModel/AdminIndex/
        /// <summary>
        /// Displays a list of all questions with an option to delete
        /// </summary>
        /// <returns>an ActionResult containing all questions</returns>
        [Authorize(Roles="Admin")]
        public ActionResult AdminIndex()
        {
            IEnumerable<Question> questions = qdb.Questions.ToList();
            List<QuestionAndResponsesModel> models = new List<QuestionAndResponsesModel>();
            questions = questions.Reverse();
            foreach (Question curr in questions)
            {
                models.Add(getAnswers(curr));
            }


            return View(models);


        }

        /// <summary>
        /// Determines if a question has been answered
        /// </summary>
        /// <param name="curr">Question</param>
        /// <returns>true if the question has at least one response, false otherwise</returns>
        private bool hasAnswers(Question curr)
        {
            var answers = from m in rdb.Responses
                          select m;

            answers = answers.Where(s => s.QuestionID.Equals(curr.ID));
            return answers.Any();
        }

        /// <summary>
        /// Fetches all responses corresponding to question curr    
        /// </summary>
        /// <param name="curr">Question which Responses need to be gather</param>
        /// <returns>a QuestionAndResponsesModel containing the Question curr</returns>
        private QuestionAndResponsesModel getAnswers(Question curr)
        {
            var answers = from m in rdb.Responses
                          select m;

            answers = answers.Where(s => s.QuestionID.Equals(curr.ID));
            answers = answers.OrderByDescending(x => x.Votes);

            QuestionAndResponsesModel qr = new QuestionAndResponsesModel();

            qr.Responses = answers;

            qr.Question = curr;
            qr.NewResponse = new Response();
            qr.NewResponse.QuestionID = curr.ID;
            qr.NewResponse.ParentID = curr.ID;
            return qr;
        }

        // GET: /QuestionAndResponsesModel/Details/5
        /// <summary>
        /// Displays Question and Responses details.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        public ActionResult Details(int id)
        {
            Question question = qdb.Questions.Find(id);

            return View(getAnswers(question));
        }


        // POST: /QuestionAndResponsesModel/Details/5
        /// <summary>
        /// Receives newly modified QuestionAndResponsesModel and saves new Response in DB
        /// </summary>
        /// <param name="response"> newly modified QuestionAndResponsesModel</param>
        /// <returns></returns>
        [HttpPost, Authorize]
        public ActionResult Details(QuestionAndResponsesModel response)
        {

            response.NewResponse.CreatedDate = DateTime.Now;
            response.NewResponse.LastModifiedDate = DateTime.Now;
            response.NewResponse.Votes = 0;
            //TODO getCurrentUser
            response.NewResponse.UserName = @User.Identity.Name;
            if (ModelState.IsValid)
            {
                rdb.Responses.Add(response.NewResponse);
                rdb.SaveChanges();
                return RedirectToAction("Details");
            }

            return View(response);
        }

        /// <summary>
        /// Performs a search on the question titles
        /// </summary>
        /// <param name="searchString"> string specifieng search criteria</param>
        /// <returns>an ActionResult object which contains all the QuestionAndResponses which match the search criteria
        /// </returns>
        [Authorize]
        public ActionResult SearchIndex(string searchString)
        {
            var questions = from m in qdb.Questions
                            select m;

            if (!String.IsNullOrEmpty(searchString))
            {
                questions = questions.Where(s => s.Title.Contains(searchString));
            }

            List<QuestionAndResponsesModel> models = new List<QuestionAndResponsesModel>();

            foreach (Question curr in questions)
            {

                models.Add(getAnswers(curr));
                if (models.Count > 9)
                {
                    break;
                }
            }


            return View(models);
        }
    }
}
